/*
 * Created on Mar 18, 2005
 * Created by dfhuynh
 */
package edu.mit.simile.longwell.ui;

import org.apache.log4j.Logger;

import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.NodeIterator;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;

import edu.mit.simile.longwell.LongwellServer;
import edu.mit.simile.longwell.Profile;
import edu.mit.simile.longwell.query.IQueryModel;
import edu.mit.simile.longwell.query.Query;
import edu.mit.simile.longwell.query.QueryException;
import edu.mit.simile.longwell.query.bucket.DistinctValueBucketer;
import edu.mit.simile.longwell.query.engine.EngineUtilities;
import edu.mit.simile.longwell.schema.ISchemaModel;

/**
 * @author dfhuynh
 */
public class QueryBasedFacade extends Facade {
    final static private Logger s_logger = Logger.getLogger(QueryBasedFacade.class);
    
	final static public String s_flair_restriction = Flair.s_namespace + "restriction";
	final static public String s_flair_subject = Flair.s_namespace + "subject";
	final static public String s_flair_predicate = Flair.s_namespace + "predicate";
	final static public String s_flair_object = Flair.s_namespace + "object";
	final static public String s_flair_bucketerParameter = Flair.s_namespace + "bucketerParameter";

	final protected Query m_query;
	
	/**
	 * @param uri
	 * @param shortLabel
	 * @param contentDescription
	 * @param initialQuery
	 */
	public QueryBasedFacade(
		String uri, String shortLabel, String contentDescription, Query query) {
		
		super(uri, shortLabel, contentDescription, query.toURLQueryString());
		m_query = query;
	}

	/* (non-Javadoc)
	 * @see edu.mit.simile.longwell.ui.Facade#getCount()
	 
	public int getCount() {
		IQueryModel queryModel = (IQueryModel)
			LongwellServer.getServer().getProfile()
				.getStructuredModel(IQueryModel.class);
		
		try {
			return queryModel.queryCount(m_query, false);
		} catch (QueryException e) {
			s_logger.error(e);
			return 0;
		}
	}
	*/
	static public QueryBasedFacade constructFacade(
			Resource r, 
			String shortLabel, 
			String contentDescription, 
			Model model, 
			Profile profile) {
		
		ISchemaModel schemaModel = profile.getSchemaModel();
		
		Query query = new Query("");
		
		NodeIterator ni = model.listObjectsOfProperty(
			r, model.createProperty(s_flair_restriction));
		while (ni.hasNext()) {
			try {
				Resource restrictionResource = (Resource) ni.nextNode();
				
				try {
					Resource predicate = model.getProperty(
						restrictionResource, 
						model.createProperty(s_flair_predicate)).getResource();
					
					String bucketerParameter = "";
					String separator = "";
					boolean forward = true;
					
					NodeIterator ni2 = model.listObjectsOfProperty(
							restrictionResource, 
							model.createProperty(s_flair_subject));
					
					if (ni2.hasNext()) {
						forward = false;
					} else {
						ni2 = model.listObjectsOfProperty(
							restrictionResource, 
							model.createProperty(s_flair_object));
					}
					
					while (ni2.hasNext()) {
						RDFNode node = ni2.nextNode();
						String value = null;
						
						if (node instanceof Resource) {
							value = "r" + schemaModel.resourceToPseudoURI((Resource)node);
						} else {
							value = "l" + ((Literal) node).getString();
						}
						bucketerParameter += separator + 
							DistinctValueBucketer.encodeParameter(value);
						
						separator = ",";
					}
					
					ni2 = model.listObjectsOfProperty(
						restrictionResource, 
						model.createProperty(s_flair_bucketerParameter));
					
					while (ni2.hasNext()) {
						Literal l = (Literal) ni2.nextNode();
						
						bucketerParameter += separator + 
							DistinctValueBucketer.encodeParameter(
								l.getString());
						
						separator = ",";
					}
					
					EngineUtilities.FacetInfo info =
						EngineUtilities.getFacetInfo(
							predicate.getURI(), forward, "", profile);
					
					query.addRestriction(
						info.m_projectorName, 
						info.m_projectorParameter, 
						info.m_bucketerName, 
						bucketerParameter);
					
					continue;
				} catch (Exception e) {
				}
			} catch (Exception e) {
				s_logger.error(e);
			}
		}
		
		return new QueryBasedFacade(
			r.getURI(),
			shortLabel,
			contentDescription,
			query);
	}
}
